package com.cc.spring.service.impl;

import com.cc.spring.domain.User;
import com.cc.spring.exception.BusinessException;
import com.cc.spring.exception.BusinessExceptionCode;
import com.cc.spring.mapper.UserMapper;
import com.cc.spring.request.DiskUserRequest;
import com.cc.spring.request.UserLikeRequest;
import com.cc.spring.request.UserPwdRequest;
import com.cc.spring.resp.UserInfoResp;
import com.cc.spring.resp.UserResp;
import com.cc.spring.service.UserService;
import com.cc.spring.utils.CopyUtil;
import com.cc.spring.utils.HdfsUtil;
import com.cc.spring.utils.JWTUtil;
import com.cc.spring.utils.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    private static final Logger LOG = LoggerFactory.getLogger(HdfsUtil.class);
    @Resource
    private UserMapper userMapper;
    @Resource
    private SnowFlake snowFlake; // springboot自动注入
    @Resource
    private HdfsUtil hdfsUtil;

    @Override
    public void addUser(DiskUserRequest user) {
        User copyUser = CopyUtil.copy(user, User.class);
//        需要检测这个用户是否存在
        User userByUserName = getUserByUserName(copyUser.getUserName());
        if(!ObjectUtils.isEmpty(userByUserName)){
//            存在情况
            throw new BusinessException(BusinessExceptionCode.USER_LOGIN_NAME_EXIST);
        }
//        需要使用雪花算法生成id
        long l = snowFlake.nextId();
//        加密密码，使用MD5加密
        String s = DigestUtils.md5DigestAsHex(copyUser.getPassword().getBytes());
        copyUser.setId(l);
        copyUser.setPassword(s);
//        初始化权限和用户是否可用，不为空，那么表示外部传来的，那么这儿就不初始化
        if(ObjectUtils.isEmpty(copyUser.getPermission())) copyUser.setPermission(1);
        if(ObjectUtils.isEmpty(copyUser.getIsAble())) copyUser.setIsAble(0);
//        需要在hdfs根目录生成一个用户目录
        boolean isOK = hdfsUtil.mkdirs(copyUser.getUserName());
        if(!isOK){
            throw new BusinessException(BusinessExceptionCode.MKDIR_CREATE_ERROR);
        }
        userMapper.insert(copyUser);
    }
//    重新写一个方法用于用户信息更新，虽然可以根据id来判断是不是要添加还是更新，但是添加的代码太多了，不利于维护
//    需要保证原子性
    @Transactional
    @Override
    public void updateUserInfo(DiskUserRequest user){
        User copyUser = CopyUtil.copy(user, User.class);
        User userByUserName = getUserByUserName(copyUser.getUserName());
//        如果用户存在，还需要判断是不是自己，因为可能没有修改用户名，只需改了密码
        if(!ObjectUtils.isEmpty(userByUserName)){
//            如果id不一样，说明了用户名已被其他人注册，那么直接抛出异常
            if(!copyUser.getId().equals(userByUserName.getId())){
                throw new BusinessException(BusinessExceptionCode.USER_LOGIN_NAME_EXIST);
            }
        }else {
//         走到这儿说明更改了用户名，那么也响应的更改用户目录
            User oldUser = userMapper.selectByPrimaryKey(copyUser.getId());
            hdfsUtil.renameDirByUserName(oldUser.getUserName(),copyUser.getUserName());
//            userMapper.updateByPrimaryKey(copyUser);
        }
//                如果没有设置权限那么就是默认的
        if(ObjectUtils.isEmpty(copyUser.getPermission())) copyUser.setPermission(1);
        if(ObjectUtils.isEmpty(copyUser.getIsAble())) copyUser.setPermission(0);
        copyUser.setPassword(null);
//        少写一句，执行完上面逻辑后操作数据库
        userMapper.updateByPrimaryKey(copyUser);
    }

    @Override
    public User getUserByUserName(String userName) {
        User userByUserName = userMapper.getUserByUserName(userName);
//        System.out.println(userByUserName);
        return userByUserName;
    }

//    用户登录
    @Override
    public UserResp userLogin(DiskUserRequest diskUserRequest) {
        User copyUser = CopyUtil.copy(diskUserRequest, User.class);
        System.out.println(copyUser);
//        首先判断用户是否存在
        User userByUserName = getUserByUserName(copyUser.getUserName());
//        System.out.println(userByUserName);
//        如果用户不存在
        if(ObjectUtils.isEmpty(userByUserName)){
            LOG.info("用户不存在");
            throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
        }else {
//            如果走到这一步，那么证明userByUserName查到了用户
//            先对传递过来的密码加密在比较，
            String md5Password = DigestUtils.md5DigestAsHex(copyUser.getPassword().getBytes());
            copyUser.setPassword(md5Password);
//            用户存在，在进一步判断密码是否正确
            if(copyUser.getPassword().equals(userByUserName.getPassword())){
//                userByUserName.setPassword();
                UserResp userResp = CopyUtil.copy(userByUserName, UserResp.class);
//                生成token
                Map<String , String> map = new HashMap<>();
                map.put("userName",userResp.getUserName());
//                将用户权限加入Claim中，方便验证权限
//                System.out.println("权限："+userResp.getPermission().toString());
                map.put("permission",userResp.getPermission().toString());
                map.put("isAble",userResp.getIsAble().toString());
                String token = JWTUtil.createToken(map);
                userResp.setToken(token);
                return userResp;
            }else {
//                密码错误
                LOG.info("用户密码错误");
                throw new BusinessException(BusinessExceptionCode.LOGIN_USER_ERROR);
            }
        }
    }

//    获取所有用户，仅限于管理员使用
    @Override
    public List<UserInfoResp> getAllUser(UserLikeRequest userLikeRequest) {
//        如果不为空。那么就是模糊查询
        if(!ObjectUtils.isEmpty(userLikeRequest)){
            List<User> usersLikeUsername = userMapper.getUsersLikeUsername(userLikeRequest);
            List<UserInfoResp> userInfoResps = CopyUtil.copyList(usersLikeUsername, UserInfoResp.class);
            return userInfoResps;
        }
//        为空那么就查询所有
        List<User> users = userMapper.selectAll();
//        不应该将超级管理员也暴露出去
        List<UserInfoResp> userInfoResps = CopyUtil.copyList(users, UserInfoResp.class);
        return userInfoResps;
    }

    @Override
    public void deleteUserByUserId(Long id) {
        User user = userMapper.selectByPrimaryKey(id);
//        还需删除相应的目录
        hdfsUtil.deleteFile(user.getUserName(),"");
        userMapper.deleteByPrimaryKey(id);
    }
//    更改密码

    @Override
    public void updateUserPassword(UserPwdRequest userPwdRequest) {
//        需要对密码进行MD5加密
        userPwdRequest.setPassword(DigestUtils.md5DigestAsHex(userPwdRequest.getPassword().getBytes()));
        userMapper.updateUserPassword(userPwdRequest.getId(), userPwdRequest.getPassword());
    }

//    批量导入
    @Override
    public int batchImportUser(List<User> users) {
        for (User user1 : users) {
//            需要使用虚化算法添加主键
            long l = snowFlake.nextId();
            user1.setId(l);
//            使用MD5加密算法加密密码
            String s = DigestUtils.md5DigestAsHex(user1.getPassword().getBytes());
            user1.setPassword(s);
//            权限和是否可用判断，为空，那么就给一个默认值
            if(user1.getPermission() == null){
                user1.setPermission(1);
            }
            if(user1.getIsAble() == null){
                user1.setPermission(0);
            }
        }
        return  userMapper.batchImportUser(users);
    }
}
